package lib

import (
	"fmt"
	"reflect"
	"strconv"
)

type ConvertStruct struct{}

var Convert ConvertStruct

func init() {
	Convert = ConvertStruct{}
}

// Any2Int any转int
func (c ConvertStruct) Any2Int(data any) int {
	var resVal int
	switch data.(type) {
	case string:
		resVal = int(c.String2Int(data.(string)))
	case int:
		resVal = data.(int)
	case int8:
		resVal = int(data.(int8))
	case int16:
		resVal = int(data.(int16))
	case int32:
		resVal = int(data.(int32))
	case int64:
		resVal = int(data.(int64))
	case float64:
		resVal = int(data.(float64))
	}
	return resVal
}

// Any2String any转string
func (c ConvertStruct) Any2String(data any) string {
	var resVal string
	switch data.(type) {
	case string:
		resVal = data.(string)
	case int:
		resVal = c.IntToString(data.(int))
	case int8:
		resVal = c.Int8ToString(data.(int8))
	case int16:
		resVal = c.Int16ToString(data.(int16))
	case int32:
		resVal = c.Int32ToString(data.(int32))
	case int64:
		resVal = c.Int64ToString(data.(int64))
	}
	return resVal
}

// String2Int 字符串转int
func (c ConvertStruct) String2Int(str string) int64 {
	_int, _err := strconv.ParseInt(str, 10, 64)
	if _err != nil {
		fmt.Printf("String2Int error-->: %s\n", _err)
	}
	return _int
}

// IntToString int转字符串
func (c ConvertStruct) IntToString(cInt int) string {
	return strconv.Itoa(cInt)
}

// Int8ToString int8转字符串
func (c ConvertStruct) Int8ToString(cInt int8) string {
	return strconv.Itoa(int(cInt))
}

// Int16ToString int16转字符串
func (c ConvertStruct) Int16ToString(cInt int16) string {
	return strconv.Itoa(int(cInt))
}

// Int32ToString int32转字符串
func (c ConvertStruct) Int32ToString(cInt int32) string {
	return strconv.Itoa(int(cInt))
}

// Int64ToString int64转字符串
func (c ConvertStruct) Int64ToString(cInt int64) string {
	return strconv.Itoa(int(cInt))
}

// Map2Struct map转struct
func (c ConvertStruct) Map2Struct(f any, t any) error {
	err := Loads(Dumps(f), t)
	return err
}

// Struct2Map struct转map
func (c ConvertStruct) Struct2Map(data any) map[string]any {
	t := reflect.TypeOf(data)
	v := reflect.ValueOf(data)
	if t.Kind() == reflect.Ptr {
		t = t.Elem()
		v = v.Elem()
	}

	mapData := make(map[string]any)
	for i := 0; i < t.NumField(); i++ {
		var keyName string
		_tField := t.Field(i)
		// 默认取json tag作为字段key
		keyName = _tField.Tag.Get("json")
		if keyName == "" {
			keyName = _tField.Name
		}

		_vField := v.Field(i)
		// 不可导出
		if !_vField.CanSet() {
			continue
		}
		mapData[keyName] = _vField.Interface()
	}
	return mapData
}
